home *** CD-ROM | disk | FTP | other *** search
- #include <exec/memory.h>
- #include <intuition/intuition.h>
- #include <intuition/gadgetclass.h>
- #include <libraries/asl.h>
- #include <libraries/gadtools.h>
- #include <dos/dos.h>
- #include <fcntl.h>
- #include <stdio.h>
- #include <string.h>
- #include <stdlib.h>
- #include <clib/asl_protos.h>
- #include <clib/exec_protos.h>
- #include <clib/graphics_protos.h>
- #include <clib/gadtools_protos.h>
- #include <clib/dos_protos.h>
-
- #include "protos.h"
- #include "gadgets.h"
- #include "defs.h"
-
- extern UBYTE ScanFileSpec[256]; /* filename for binary scan */
- extern struct Screen *Scr; /* screen we open up on */
- extern USHORT *SavePal; /* Snapshot of current palette*/
- extern UWORD CycleSelect = 0; /* ordinal value of cycle gad */
- extern UBYTE LoadFile[32];
- extern UBYTE LoadDir[224];
- extern UBYTE ScanFile[32];
- extern UBYTE ScanDir[224];
- extern UBYTE FileSpec[224];
-
- ULONG *OffSetABase = NULL; /* ptr to file offsets */
- UBYTE **OffSetSBase = NULL; /* ptr to file offset strings */
- SHORT OffSetCount = 0; /* number of offsets found */
-
-
- /*-------------------------------------------------------------------------
- * ASL requester tags & data.
- *-------------------------------------------------------------------------*/
-
- #define FILESAVE 0
- #define FILELOAD 1
- #define FILESCAN 2
-
-
-
-
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * CAUTION! ASL_Window in the following structures is position sensitive
- * due to initialization in FileSelect(). It must be the first item
- * in the TagItem structure.
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- struct TagItem SaveTags[] = {
- ASL_Window, NULL, /* the window */
- ASL_Hail, "Save File:", /* Function text */
- ASL_File, LoadFile, /* file name buffer */
- ASL_Dir, LoadDir, /* path name buffer */
- ASL_OKText, "Save", /* "OK" Text */
- TAG_DONE };
-
- struct TagItem LoadTags[] = {
- ASL_Window, NULL, /* the window */
- ASL_Hail, "Load File:", /* Function text */
- ASL_File, LoadFile, /* file name buffer */
- ASL_Dir, LoadDir, /* path name buffer */
- ASL_OKText, "Load", /* "OK" Text */
- TAG_DONE };
-
- struct TagItem ScanTags[] = {
- ASL_Window, NULL, /* the window */
- ASL_Hail, "Scan File:", /* Function text */
- ASL_File, ScanFile, /* file name buffer */
- ASL_Dir, ScanDir, /* path name buffer */
- ASL_OKText, "Scan", /* "OK" Text */
- TAG_DONE };
-
- struct TagItem *FileTags[] = { SaveTags,
- LoadTags,
- ScanTags };
-
-
-
- /*=============================================================================
- * Open an ASL file requester for either LOAD, SAVE or SCAN, depending on
- * "mode" argument
- *===========================================================================*/
-
- BOOL FileSelect( int mode, UBYTE *dir, UBYTE *file )
- {
- struct FileRequester *freq;
- struct TagItem *Tags;
- BOOL fileselected;
-
- fileselected = FALSE;
- Tags = FileTags[mode];
-
- /*~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
- * CAUTION! In order for the following statement to work, "ASL_Window"
- * must be the first Item in the TagItem array
- *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~*/
-
- Tags->ti_Data = (ULONG)ColorSaverWnd;
-
-
- if ( freq = AllocAslRequest( ASL_FileRequest, Tags )) {
- if ( RequestFile( freq )) {
- strcpy( dir, freq->rf_Dir );
- strcpy( FileSpec, freq->rf_Dir );
- strcpy( file, freq->rf_File );
- (void)AddPart(FileSpec,file,(ULONG)sizeof(FileSpec));
- fileselected = TRUE;
- }
-
- FreeAslRequest( freq );
- }
-
- return(fileselected);
-
- }
-
- /*=============================================================================
- * Save a color palette
- *===========================================================================*/
-
- void SaveColors( UBYTE *file, ULONG colors )
- {
-
- int fh;
- int w;
-
- if ((fh = open((char *)file, O_WRONLY|O_CREAT|O_TRUNC)) >= 0)
- {
- CopyMem((void *)Scr->ViewPort.ColorMap->ColorTable,(void *)SavePal,64L);
- w = write(fh, (void *)SavePal, colors << 1);
- close(fh);
- if( w != colors << 1 )
- (void)Notify(FILE_WRITE_IOERR, file);
- }
- else
- (void)Notify(FILE_OPEN_FAIL, file);
- }
-
-
- /*=============================================================================
- * Load a color palette
- *===========================================================================*/
-
- void LoadColors( UBYTE *file, ULONG colors )
- {
-
- int fh;
- long filelen, bytesread, colorbytes;
- USHORT *palette;
- BOOL loadanyway = FALSE;
-
- colorbytes = colors << 1;
-
- if(!(palette = AllocMem(64L,MEMF_PUBLIC))) {
- (void)Notify(LOAD_MALLOC_FAIL);
- return;
- }
-
- if ((fh = open(file,O_RDONLY)) >= 0) { /* Try to open input file */
- bytesread = read(fh, (char *)palette, colorbytes);
- filelen = lseek(fh,0L,2); /* Get the file length */
- close(fh);
- }
-
- else { /* Couldn't open the file */
- (void)Notify(FILE_OPEN_FAIL, file);
- return;
- }
-
- if (bytesread < 0) { /* Uh-Oh! Read Error! */
- (void)Notify(FILE_READ_IOERR, file);
- return;
- }
- /*
- * If there are not enough or too many bytes in the file to match the
- * number of BitPlanes, alert the user
- */
-
- if ((colorbytes > bytesread)||(filelen > colorbytes))
- loadanyway = Notify(PALETTE_SIZE_MISMATCH, colors, filelen >> 1);
-
- if(loadanyway || (bytesread == filelen) && (filelen == colorbytes))
- {
- LoadRGB4(&Scr->ViewPort,palette, filelen >> 1);
- }
- }
-
-
- /*=============================================================================
- * Search a binary file for its Color Table
- *===========================================================================*/
- #define BUFSIZE 4096L /* size of I/O buffer */
-
- void *FindTable( UBYTE *file, USHORT *palette, ULONG colors )
- {
- char *inbuffer;
- long offset;
- char *buffptr; /* memory pointer */
- int bytesread=0; /* bytes transferred during each read */
- long filepos=0; /* total bytes to have been read in */
- int fh;
-
- OffSetCount = 0;
-
- if ((fh= open(file,O_RDONLY)) < 0) { /* try to open input file */
- (void)Notify(FILE_OPEN_FAIL, file);
- return;
- }
-
- if(!(inbuffer = AllocMem(BUFSIZE,MEMF_PUBLIC))) {
- (void)Notify(BUFFER_MALLOC_FAIL);
- return;
- }
-
- /*
- * read in the first block of chars
- */
-
- bytesread= read(fh,inbuffer,BUFSIZE);
- buffptr=inbuffer;
-
- for (;;)
- {
-
- if(memcmp((void *)buffptr,(void *)palette,colors<<1)==0)
- { /* did we get a match ?? */
- filepos=lseek(fh,0L,1);
- offset=((filepos-bytesread)+(buffptr-inbuffer));
- if(AddOffSet(offset) < 0)
- (void)Notify(OFFSET_MALLOC_FAIL);
- }
- buffptr++;
-
- /*
- * this next bit of code counters the possibility of having the search
- * palette chopped off at the end of the buffer, (would be my luck!)
- * if less than sizeof(palette) bytes remain in the buffer, an lseek
- * backwards is done and these are read back in to the beginning
- * of the next buffer full
- */
-
- if((BUFSIZE -(buffptr-inbuffer)) < colors<<1)
- {
- filepos=lseek(fh,-colors<<1,1);
- bytesread= read(fh,inbuffer,BUFSIZE);
- filepos=lseek(fh,0L,1);
- buffptr=inbuffer; /* reset pointers to start of buffer */
- }
- if(buffptr-inbuffer > bytesread) /* got to the end of the file */
- break;
- }
-
- close(fh);
-
-
- if(OffSetCount == 0) /* Couldn't find a Color Table match */
- {
- if(OffSetABase)
- FreeOffSets();
-
- (void)Notify(NO_COLORTABLE_FOUND);
-
- GT_SetGadgetAttrs(GAD(GD_CYCLE_GAD),ColorSaverWnd,NULL,GTCY_Labels,
- CYCLE_GAD0Labels,GA_Disabled, TRUE,TAG_END);
- GT_SetGadgetAttrs(GAD(GD_WRITE_GAD),ColorSaverWnd,NULL,GA_Disabled,
- TRUE,TAG_END);
- }
- else
- {
- GT_SetGadgetAttrs(GAD(GD_CYCLE_GAD),ColorSaverWnd,NULL,GTCY_Labels,
- OffSetSBase,GA_Disabled, FALSE,TAG_END);
- GT_SetGadgetAttrs(GAD(GD_WRITE_GAD),ColorSaverWnd,NULL,GA_Disabled,
- FALSE,TAG_END);
- if(OffSetCount == 1)
- (void)Notify(ONE_COLORTABLE_FOUND);
- else
- (void)Notify(MULT_COLORTABLE_FOUND,OffSetCount);
-
- strcpy(ScanFileSpec,file);
- }
-
- if(inbuffer) FreeMem(inbuffer,BUFSIZE);
-
- }
-
-
- #define OFFSETBUFSZ 8 /* number of characters in cycle gadget */
-
- int AddOffSet(ULONG offset)
- {
- ULONG *OffSetAPtr; /* pointer to place to store actual offset */
- UBYTE *OffSetBuf; /* pointer to place to store string version of above */
- UBYTE **OffSetSPtr; /* pointer to array of above strings */
-
- OffSetCount++;
-
- /*-------------------------------------------------------------------------
- * Store the offset in a continuously increasing array
- *-------------------------------------------------------------------------*/
- if(( OffSetABase = (ULONG *)realloc
- (OffSetABase, OffSetCount * sizeof(ULONG))) == NULL)
- return(-1);
-
- OffSetAPtr = OffSetABase + (OffSetCount -1);
- *OffSetAPtr = offset;
-
-
- /*-------------------------------------------------------------------------
- * Allocate memory to hold the offset in string form
- *-------------------------------------------------------------------------*/
- if(( OffSetBuf = (UBYTE *)malloc(OFFSETBUFSZ)) == NULL)
- return(-1);
-
- /*--------------------------------------------------------------------------
- * Store pointers to the above strings in a continuously increasing array
- *-------------------------------------------------------------------------*/
- if(( OffSetSBase=(UBYTE **)realloc
- (OffSetSBase,((OffSetCount+1) * sizeof(UBYTE **)))) == NULL)
- return(-1);
-
- OffSetSPtr = OffSetSBase + (OffSetCount -1);
- *OffSetSPtr = OffSetBuf;
-
- /*-------------------------------------------------------------------------
- * String pointer array needs to be NULL terminated for GadTools cycle
- * gadget
- *-------------------------------------------------------------------------*/
- *(++OffSetSPtr) = NULL;
- sprintf(OffSetBuf,"%7d",offset);
-
- return(0);
-
- }
-
- void FreeOffSets( void )
- {
- UBYTE **sptr;
- ULONG *optr;
- USHORT i;
-
- optr = OffSetABase; /* Set pointers to head of actual offset array */
- sptr = OffSetSBase; /* and also to array of pointers to strings */
-
- for(i = 0; i < OffSetCount; i++, optr++, sptr++)
- {
- if(*sptr)free(*sptr); /* Free the string */
- if( sptr)free(sptr); /* ...now free the pointer to the string */
- if( optr)free(optr); /* ...and now the actual offset */
- }
-
- OffSetABase = NULL; /* need to invalidate these pointers too... */
- OffSetSBase = NULL;
-
- }
-
- /*=============================================================================
- * Write the new colors out to the file.
- *===========================================================================*/
-
- void Patch( UBYTE *file, USHORT *palette, ULONG colors )
- {
-
- int fh;
- int w;
- int doit;
- ULONG offset;
-
- offset = (ULONG) *(OffSetABase + CycleSelect);
-
- doit = Notify(ABOUT_TO_WRITE, file, offset);
-
- if ( !doit )
- return;
-
- if ( (fh = open(file,O_RDWR) ) < 0 ){ /* Try to open input file */
- (void)Notify(FILE_OPEN_FAIL, file);
- return;
- }
- else
- {
- lseek(fh,offset,0); /* position to start of palette */
- w = write(fh, (void *)palette, colors << 1);
- close(fh);
- if( w != colors << 1 )
- (void)Notify(FILE_WRITE_IOERR, file);
- else
- (void)Notify(WRITE_SUCCESS);
- }
-
- }
-